#!/usr/bin/env python
"""
Nagios plugin that checks gridsecurity (/etc/gridsecurity) environment. It 
verifies whether relevant directories and files exists. It monitors the age of 
the grid-mapfile and the usage of poolaccounts.. 

todo:   - check for vomsdir content (validity etc.)
"""

__author__ = "Placi Flury grid@switch.ch"
__copyright__ = "Copyright 2010, SMSCG an AAA/SWITCH project"
__date__ = "26.08.2009"
__version__ = "0.2.0"

# last modifications:
# stripped off pool-account usage reporting (done by separate plugin)   20.7. 2009
# last change   -> shorter 'output' message due to nodutils 255 char limits


import sys
from os import environ
import os.path
from time import time
from nagios_plugin import NagiosPluginBasic
from nagios_plugin import RETURN_CODE

class GridSecurityDir(NagiosPluginBasic):

    def __init__(self):
        pass

    def getOptions(self):
        parser = NagiosPluginBasic.getOptions(self)

        parser.add_option("", "--node_type", action="store",
                        dest="node_type", default="NG_CE",
                        help="Defines the type of the node that is to be checked. \
                            Current options are: \"NG_UI\" (NorduGrid UI), \
                            \"NG_CE \" (NorduGrid CE) (default: NG_CE).")

        valid_types = ["NG_UI", "NG_CE"]

        self.options, self.args = parser.parse_args()

        if self.options.node_type and not self.options.node_type in valid_types:
            print "UNKNOWN: grid node type '%s' invalid" % self.options.node_type
            sys.exit(RETURN_CODE["unknown"])

        if not self.options.critical_thresh:
            self.options.critical_thresh = 12 # 12 hours 
        if not self.options.warn_thresh:
            self.options.warn_thresh = 48 # 48 hours



    def check_env(self):
        """
        check whether environment is set up properly

        returns: 1 everything is fine
                 0  something is missing or wrong
        """

        missing = {}

        self.grid_security_path = environ.get("GRID_SECURITY_PATH", "/etc/grid-security");

        if not os.path.exists(self.grid_security_path):
            missing["GRID_SECURITY_PATH"] = self.grid_security_path

        if missing:
            print "CRITICAL: environment not found"
            if self.verbosity > 0:  
                for i in missing.keys():
                    print "Please set environment '$%s=%s' correctly." % (i, missing[i])
            sys.exit(RETURN_CODE["critical"]) 

        certdir = os.path.join(self.grid_security_path, "certificates")
        vomsdir = os.path.join(self.grid_security_path, "vomsdir")

        if not os.path.exists(certdir):
            print "CRITICAL: Security anchor '%s' not found" % certdir
            sys.exit(RETURN_CODE["critical"])

        if not os.path.exists(vomsdir):
            print "CRITICAL: Security anchor '%s' not found" % vomsdir
            sys.exit(RETURN_CODE["critical"])

        if self.options.node_type == "NG_CE":
            self.gridmapdir = os.path.join(self.grid_security_path, "gridmapdir")
            self.grid_mapfile = os.path.join(self.grid_security_path, "grid-mapfile")
            groupmapfile = os.path.join(self.grid_security_path, "groupmapfile")
            fqan_mappings_file = os.path.join(self.grid_security_path, "fqan_mappings.txt")
            banned_users_file = os.path.join(self.grid_security_path, "banned_users.txt")

            if not os.path.exists(self.gridmapdir):
                print "CRITICAL: gridmapdir not found in '%s'\n" % self.gridmapdir
                sys.exit(RETURN_CODE["critical"])

            msg, code = NagiosPluginBasic.file_check(self, self.grid_mapfile, "grid-mapfile")
            self.__isOk(msg,code)
            NagiosPluginBasic.file_check(self, groupmapfile, "groupmapfile")
            self.__isOk(msg,code)
            NagiosPluginBasic.file_check(self, fqan_mappings_file, "fqan_mappings.txt")
            self.__isOk(msg,code)
            NagiosPluginBasic.file_check(self, banned_users_file, "banned_users.txt")
            self.__isOk(msg,code)


    def __isOk(self,msg,code):
        if code != RETURN_CODE["ok"]: 
            print msg
            sys.exit(code)



    def main(self):
        self.getOptions()
        self.check_env()

        if self.options.node_type == "NG_CE":
            # check gridmapfile age -> warn if not updated regularily
            age  = time() - os.path.getmtime(self.grid_mapfile)
            if (age > (self.options.critical_thresh * 60 * 60)):
                print "CRITICAL: gridmap-file at %s is older than %d hours"\
                     % (self.grid_mapfile, self.options.critical_thresh)
                sys.exit(RETURN_CODE["critical"])
            if (age > (self.options.warn_thresh * 60 * 60)):
                print "WARNING: gridmap-file at %s is older than %d hours"\
                     % (self.grid_mapfile, self.options.warn_thresh)
                sys.exit(RETURN_CODE["warning"])


        print "OK: security settings checked."
        sys.exit(RETURN_CODE["ok"])

if __name__ == "__main__":

    gsd = GridSecurityDir()
    gsd.main()
